//
//  HXWebViewController.m
//  butterfly
//
//  Created by Mudmen on 2021/1/15.
//

#import "SCWebViewController.h"
#import "HXWKWebViewJavascriptBridge.h"
#import <sys/utsname.h>

typedef NS_ENUM(NSUInteger,LoadStatus)
{
    LoadStatusWillLoad          = 0,//webView将要开始加载
    LoadStatusLoading           = 1,//webView正在加载中
    LoadStatusLoaded            = 2,//webView已经加载完成
};

@interface SCWebViewController () <WKNavigationDelegate,WKUIDelegate> {
    UIBarButtonItem         *closeBarButtonItem;
    UIActivityIndicatorView *indicatorView;
    LoadStatus              loadStatus;
}

@property HXWKWebViewJavascriptBridge *bridge;

/**
 *  array that hold snapshots
 */
@property (nonatomic)NSMutableArray* snapShotsArray;

/**
 *  current snapshotview displaying on screen when start swiping
 */
@property (nonatomic)UIView* currentSnapShotView;

/**
 *  previous view
 */
@property (nonatomic)UIView* prevSnapShotView;

/**
 *  background alpha black view
 */
@property (nonatomic)UIView* swipingBackgoundView;

/**
 *  left pan ges
 */
@property (nonatomic)UIPanGestureRecognizer* swipePanGesture;

/**
 *  if is swiping now
 */
@property (nonatomic)BOOL isSwipingBack;
@end

@implementation SCWebViewController

- (void)dealloc{
    [[NSNotificationCenter defaultCenter]removeObserver:self];
}

- (void)setUrlPath:(NSString *)urlPath {
  if (urlPath.length) {
      _urlPath = sc_url_web(urlPath);
  } else {
      _urlPath = @"";
  }
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    //监听UIWindow隐藏

    loadStatus = LoadStatusWillLoad;

    WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
    //设置为YES即可
    config.allowsInlineMediaPlayback = YES;
    
    wkWebView_ = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:config];
    wkWebView_.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
  [wkWebView_ loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:self.urlPath]]];
    wkWebView_.UIDelegate = self;
    wkWebView_.navigationDelegate = self;
    wkWebView_.scrollView.decelerationRate = UIScrollViewDecelerationRateNormal;
    wkWebView_.backgroundColor = [UIColor colorWithHexString:APP_BACKGROUNDCOLOR];
    [self.view addSubview:wkWebView_];

    [wkWebView_ addGestureRecognizer:self.swipePanGesture];

    if (@available(iOS 11.0, *)) {
        wkWebView_.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
    } else {
        self.automaticallyAdjustsScrollViewInsets = NO;
    }

    [HXWKWebViewJavascriptBridge enableLogging];
    _bridge = [HXWKWebViewJavascriptBridge bridgeForWebView:wkWebView_];
    [_bridge setWebViewDelegate:self];
    
    __weak typeof (self) weakSelf = self;
    [_bridge registerHandler:@"submitFromWeb" handler:^(id data, WVJBResponseCallback responseCallback) {
        [weakSelf handlerWithdata:data];
    }];
    
    indicatorView = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
    [indicatorView setCenter:CGPointMake(self.view.frame.size.width / 2, self.view.frame.size.height / 2)];
    [self.view addSubview:indicatorView];

    UIButton *closeBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    closeBtn.frame = CGRectMake(0, 0, 40, 25);
    [closeBtn setTitle:@"关闭" forState:UIControlStateNormal];
    [closeBtn setTitleColor:[UIColor colorWithHexString:NORMAL_GRAY_COLOR] forState:UIControlStateNormal];
    closeBtn.titleLabel.font = [SCAppAppearance defaultContentFontWithSize:15.0f];
    [closeBtn addTarget:self action:@selector(closeWebAction) forControlEvents:UIControlEventTouchUpInside];
    closeBtn.titleEdgeInsets = UIEdgeInsetsMake(0, -20, 0, 0);
    closeBarButtonItem = [[UIBarButtonItem alloc]initWithCustomView:closeBtn];
    
}

- (void)handlerWithdata:(id)data
{

}

#pragma mark - swiping
- (UIView*)swipingBackgoundView{
    if (!_swipingBackgoundView) {
        _swipingBackgoundView = [[UIView alloc] initWithFrame:self.view.bounds];
        _swipingBackgoundView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.3];
    }
    return _swipingBackgoundView;
}

- (NSMutableArray*)snapShotsArray{
    if (!_snapShotsArray) {
        _snapShotsArray = [NSMutableArray array];
    }
    return _snapShotsArray;
}

- (BOOL)isSwipingBack{
    if (!_isSwipingBack) {
        _isSwipingBack = NO;
    }
    return _isSwipingBack;
}

-(UIPanGestureRecognizer*)swipePanGesture{
    if (!_swipePanGesture) {
        _swipePanGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(swipePanGestureHandler:)];
    }
    return _swipePanGesture;
}

#pragma mark - action
- (void)back
{
    if ([wkWebView_ canGoBack]) {
        [wkWebView_ goBack];
    }
    else
    {
        [self.navigationController popViewControllerAnimated:YES];
    }
}

- (void)closeWebAction
{
    [self.navigationController popViewControllerAnimated:YES];
}

- (void)tapCloseButton {
    [self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}

#pragma mark - WKWebView delegate
- (void)webView:(WKWebView *)webView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error
{
    [indicatorView stopAnimating];
    loadStatus = LoadStatusLoaded;
}

- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation
{
    [indicatorView startAnimating];
    loadStatus = LoadStatusWillLoad;
    [self updateNavigationItems];
}

- (nullable WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures
{
    [webView loadRequest:navigationAction.request];
    return nil;
}

- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler {
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
        if ([challenge previousFailureCount] == 0) {
            NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
            completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
        } else {
            completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
        }
    } else {
        completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
    }
}

- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
{
    loadStatus = LoadStatusLoaded;
    [indicatorView stopAnimating];
    [self updateNavigationItems];
    NSString *theTitle=webView.title;
    
    if (!_forbiddenTitle) {
        self.title = theTitle;
    }
}

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
    //  在发送请求之前，决定是否跳转
    //    decisionHandler(WKNavigationActionPolicyAllow);
    //    return;

  NSURLRequest *urlRequest = navigationAction.request;
    switch (navigationAction.navigationType) {
        case WKNavigationTypeLinkActivated: {
            [self pushCurrentSnapshotViewWithRequest:urlRequest];
        }
            break;
        case WKNavigationTypeFormSubmitted: {
            [self pushCurrentSnapshotViewWithRequest:urlRequest];
        }
            break;
        case WKNavigationTypeBackForward: {
            break;
        }
        case WKNavigationTypeReload: {
            break;
        }
        case WKNavigationTypeFormResubmitted: {
            break;
        }
        case WKNavigationTypeOther: {
//            NSLog(@"WKNavigationTypeOther");
//            [self pushCurrentSnapshotViewWithRequest:navigationAction.request];
        }
            break;
        default: {
            break;
        }
    }
    
    [self updateNavigationItems];
    decisionHandler(WKNavigationActionPolicyAllow);
}

#pragma mark - events handler
- (void)swipePanGestureHandler:(UIPanGestureRecognizer*)panGesture{
    CGPoint translation = [panGesture translationInView:wkWebView_];
    //CGPoint location = [panGesture locationInView:webView_];
    
    if (panGesture.state == UIGestureRecognizerStateBegan) {
        [self startPopSnapshotView];
        //        if (location.x <= 60 && translation.x > 0) {  //开始动画
        //            [self startPopSnapshotView];
        //        }
    }else if (panGesture.state == UIGestureRecognizerStateCancelled || panGesture.state == UIGestureRecognizerStateEnded){
        [self endPopSnapShotView];
    }else if (panGesture.state == UIGestureRecognizerStateChanged){
        [self popSnapShotViewWithPanGestureDistance:translation.x];
    }
}

- (void)startPopSnapshotView{
    if (self.isSwipingBack) {
        return;
    }
    if (!wkWebView_.canGoBack) {
        return;
    }
    
    self.isSwipingBack = YES;
    //create a center of scrren
    CGPoint center = CGPointMake(self.view.bounds.size.width/2, self.view.bounds.size.height/2);
    
    self.currentSnapShotView = [wkWebView_ snapshotViewAfterScreenUpdates:YES];
    
    //add shadows just like UINavigationController
    self.currentSnapShotView.layer.shadowColor = [UIColor blackColor].CGColor;
    self.currentSnapShotView.layer.shadowOffset = CGSizeMake(3, 3);
    self.currentSnapShotView.layer.shadowRadius = 5;
    self.currentSnapShotView.layer.shadowOpacity = 0.75;
    
    //move to center of screen
    self.currentSnapShotView.center = center;
    
    self.prevSnapShotView = (UIView*)[[self.snapShotsArray lastObject] objectForKey:@"snapShotView"];
    center.x -= 60;
    self.prevSnapShotView.center = center;
    self.prevSnapShotView.alpha = 1;
    self.view.backgroundColor = [UIColor blackColor];
    
    [self.view addSubview:self.prevSnapShotView];
    [self.view addSubview:self.swipingBackgoundView];
    [self.view addSubview:self.currentSnapShotView];
}

- (void)popSnapShotViewWithPanGestureDistance:(CGFloat)distance{
    if (!self.isSwipingBack) {
        return;
    }
    
    if (distance <= 0) {
        return;
    }
    
    CGPoint currentSnapshotViewCenter = CGPointMake(self.view.frame.size.width/2, self.view.frame.size.height/2);
    currentSnapshotViewCenter.x += distance;
    CGPoint prevSnapshotViewCenter = CGPointMake(self.view.frame.size.width/2, self.view.frame.size.height/2);
    prevSnapshotViewCenter.x -= (self.view.frame.size.width - distance)*60/self.view.frame.size.width;
    //    NSLog(@"prev center x%f",prevSnapshotViewCenter.x);
    
    self.currentSnapShotView.center = currentSnapshotViewCenter;
    self.prevSnapShotView.center = prevSnapshotViewCenter;
    self.swipingBackgoundView.alpha = (self.view.frame.size.width - distance)/self.view.frame.size.width;
}

- (void)endPopSnapShotView {
    if (!self.isSwipingBack) {
        return;
    }
    
    //prevent the user touch for now
    self.view.userInteractionEnabled = NO;
    
    if (self.currentSnapShotView.center.x >= self.view.frame.size.width) {
        // pop success
        [UIView animateWithDuration:0.2 animations:^{
            [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
            
            self.currentSnapShotView.center = CGPointMake(self.view.frame.size.width*3/2, self.view.frame.size.height/2);
            self.prevSnapShotView.center = CGPointMake(self.view.frame.size.width/2, self.view.frame.size.height/2);
            self.swipingBackgoundView.alpha = 0;
        }completion:^(BOOL finished) {
            [self.prevSnapShotView removeFromSuperview];
            [self.swipingBackgoundView removeFromSuperview];
            [self.currentSnapShotView removeFromSuperview];
            [wkWebView_ goBack];
            
            [self.snapShotsArray removeLastObject];
            self.view.userInteractionEnabled = YES;
            
            self.isSwipingBack = NO;
        }];
    }else{
        //pop fail
        [UIView animateWithDuration:0.2 animations:^{
            [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
            
            self.currentSnapShotView.center = CGPointMake(self.view.frame.size.width/2, self.view.frame.size.height/2);
            self.prevSnapShotView.center = CGPointMake(self.view.frame.size.width/2-60, self.view.frame.size.height/2);
            self.prevSnapShotView.alpha = 1;
        }completion:^(BOOL finished) {
            [self.prevSnapShotView removeFromSuperview];
            [self.swipingBackgoundView removeFromSuperview];
            [self.currentSnapShotView removeFromSuperview];
            self.view.userInteractionEnabled = YES;
            
            self.isSwipingBack = NO;
        }];
    }
}

#pragma mark - update nav items

- (void)updateNavigationItems{

    if (wkWebView_.canGoBack) {
        [wkWebView_ addGestureRecognizer:self.swipePanGesture];
        self.navigationController.interactivePopGestureRecognizer.enabled = NO;
        [backBtn setImage:[UIImage imageNamed:@"back_icon"] forState:UIControlStateNormal];
        [backBtn setTitle:@"返回" forState:UIControlStateNormal];
        backBtn.frame = CGRectMake(backBtn.frame.origin.x, backBtn.frame.origin.y, 45, backBtn.frame.size.height);
        backBtn.imageEdgeInsets = UIEdgeInsetsMake(0, -20, 0, 0);
        if (self.leftBarItem) {
             self.navigationItem.leftBarButtonItems = @[self.leftBarItem,closeBarButtonItem];
        }else{
             self.navigationItem.leftBarButtonItems = @[closeBarButtonItem];
        }
    } else{
        [wkWebView_ removeGestureRecognizer:self.swipePanGesture];
        self.navigationController.interactivePopGestureRecognizer.enabled = YES;
        [backBtn setImage:[UIImage imageNamed:@"back_icon"] forState:UIControlStateNormal];
        [backBtn setTitle:nil forState:UIControlStateNormal];
        backBtn.frame = CGRectMake(backBtn.frame.origin.x, backBtn.frame.origin.y, 60, backBtn.frame.size.height);
        backBtn.imageEdgeInsets = UIEdgeInsetsMake(0, -45, 0, 0);
        self.navigationItem.leftBarButtonItems = nil;
        self.navigationItem.leftBarButtonItem = self.leftBarItem;
    }
}

#pragma mark - logic of push and pop snap shot views
- (void)pushCurrentSnapshotViewWithRequest:(NSURLRequest*)request{
    //    NSLog(@"push with request %@",request);
    NSURLRequest* lastRequest = (NSURLRequest*)[[self.snapShotsArray lastObject] objectForKey:@"request"];
    
    //如果url是很奇怪的就不push
    if ([request.URL.absoluteString isEqualToString:@"about:blank"]) {
        //        NSLog(@"about blank!! return");
        return;
    }
    //如果url一样就不进行push
    if ([lastRequest.URL.absoluteString isEqualToString:request.URL.absoluteString]) {
        return;
    }
    
    UIView* currentSnapShotView = [wkWebView_ snapshotViewAfterScreenUpdates:YES];
    [self.snapShotsArray addObject:
     @{
       @"request":request,
       @"snapShotView":currentSnapShotView
       }
     ];
}

#pragma mark - webViewReload
- (void)reload
{
    [wkWebView_ reload];
}

@end
